/*
 * @文件描述: 示波器model
 * @版本: 
 * @作者: 周晨阳
 * @Date: 2021-01-13 23:26:12
 * @说明：
 * 负责示波器的所有逻辑
 * 该文件为纯c文件，没有直接控制硬件的代码，如需要移植到其他平台
 * 只需要额外实现V开头的函数，除此之外的函数都为纯c文件
 * 所使用到的模块也都为对应的函数调用，只需要实现对应的函数既可以移植
 * 个别非标准的结构体，只需要稍微实现一下即可
 */
#include "oscilloscope.h"
#include "OscilloscopePre.h"
#include "myADC.h"
#include "DAC.h"
//#include "arm_math.h"
#include "myButton.h"
#include "myTimer.h"
#include "interpolation.h"
#include "filter.h"
#include "beeper.h"
#include "homePage.h"
#include "unitCondi.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
//最大ADC_DMA缓存大小
#define ADC_DMA_BUFFER_SIZE OSCILL_STORAGE_SIZE
//最大存储深度
#define VALID_BUFFER_SIZE (ADC_DMA_BUFFER_SIZE * 2)

#define Y_MIDDEL 210
#define X_MIDDEL 395
#define METER_WINDOW_WIDTH 730
#define PIXEL_PER_SCALE (METER_WINDOW_WIDTH / 10)
//顶部波形指示窗口
#define TOP_WAVE_WIN_X1 163
#define TOP_WAVE_WIN_Y1 1
#define TOP_WAVE_WIN_X2 621
#define TOP_WAVE_WIN_Y2 28

#define TOP_WAVE_WIN_WIDTH (TOP_WAVE_WIN_X2 - TOP_WAVE_WIN_X1)
#define TOP_WAVE_WIN_HEIGHT (TOP_WAVE_WIN_Y2 - TOP_WAVE_WIN_Y1)

#define LEFT_INFO_ID_FREQ 0
#define LEFT_INFO_ID_CURA 1
#define LEFT_INFO_ID_CURB 2
#define LEFT_INFO_ID_DX 3
#define LEFT_INFO_ID_FX 4
#define LEFT_INFO_ID_CURC 5
#define LEFT_INFO_ID_CURD 6
#define LEFT_INFO_ID_DY 7

/* Private macro -------------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
static void infoListInit(void);

static void onEncoderV_ScaleRotated(uint8_t dir);
static void onEncoderH_ScaleRotated(uint8_t dir);
static void onEncoderH_PosRotated(uint8_t dir);
static void onEncoderV_PosRotated(uint8_t dir);
static void onCursorRotated(uint8_t dir);
static void onV_Pos_Reset(void);
static void onH_Pos_Reset(void);
static void onTriggerRotated(uint8_t dir);
static void onTriggerReset(void);
static void onF1ButtonClicked(void);
static void onF2ButtonClicked(void);
static void onF3ButtonClicked(void);
static void onF4ButtonClicked(void);
static void onF5ButtonClicked(void);

static void oneSecondTimerCallback(void);

static void measureVpp(void *p);
static void measureVmin(void *p);
static void measureVmax(void *p);
static void measureVrms(void *p);

static void measureFreq(void *p);
static void CurAprocess(void *p);
static void CurBprocess(void *p);
static void dyProcess(void *p);
static void fxProcess(void *p);
static void CurCprocess(void *p);
static void CurDprocess(void *p);
static void dxProcess(void *p);

static void cursorUpdate(Cursor *list);
static rt_timer_t timer;
static uint8_t keyState = 0;

/* Private variables ---------------------------------------------------------*/
//当前垂直时基宏
static uint8_t currentH_Scare = H_SCALE_200US;
//当前水平时基宏
static uint8_t currentV_Scare = V_SCALE_5V;

//当前垂直时基实际数值，单位V
static float currentV_ScareValue = 0;
//当前水平时基实际数值，单位ns
static uint32_t currentH_ScareValue = 0;
//当前水平时基所使用的实时采样率,单位Sa/s
static uint32_t SamplingRate;
//屏幕左侧第一个数据点在validbuffer中的index
uint16_t trueDataStartPos;

//存储深度
static uint32_t StorageDepth = ADC_DMA_BUFFER_SIZE;

static float triggerPercent = 0.5f;

//光标，包括两个横向光标，两个纵向光标，一个触发位置光标
static Cursor CursorList[5];

//垂直和水平偏移，单位为像素
static int currentV_Pos = 0;
static int currentH_Pos = 0;

//触发电压指示线在屏幕中的位置，以中心线为0，往上为正，往下为负
static uint16_t currentTrigLinePos;

//运行状态
static uint8_t RuningState = STATE_RUNNING;
//触发方式
static uint8_t TrigType = TRIG_TYPE_RISING;
//触发电压，不同垂直时基下的触发电压不同
static float TrigVoltage = 0;

//ADC三重交替采样DMA专用缓冲区，由DMA负责数据转移
static __IO uint32_t buffer0[ADC_DMA_BUFFER_SIZE];

//有效数据缓冲，由程序负责数据处理
static __IO uint16_t validBuffer[ADC_DMA_BUFFER_SIZE * 2];
static uint16_t ValidDataSize = ADC_DMA_BUFFER_SIZE * 2;

//触发系统缓冲
static uint16_t triggerBuffer[ADC_DMA_BUFFER_SIZE * 2];

//有效数据总时长,单位us
static uint32_t validDataDuration;
//显示区域总时长，单位ns
static uint32_t displayDataDuration;
//二者之比
static float _k;
//显示一个窗口需要的采样点数
static uint32_t samplePerWindow;
//触发系统频率计数器
static uint32_t Counter;
//插值方式
static uint8_t interpolaitonType = INTERPOLATION_LINEAR;
//触发系统的状态
static uint8_t TriggerState = TRIGGER_STATE_AUTO;
//显示窗口缓冲，view层会自动显示此缓冲中的数据，此数据只有前730个有效，也正好就是窗口的宽度
//730以后的数据不会显示
static __IO GUI_POINT displayData[750];

//测量信息list
#define INFO_LIST_CNT MEASURE_TOTAL_CNT
#define MENU_ITEM_CNT 9
#define LEFT_SIDE_ITEM_CNT 8
static float infoListTmp[MEASURE_TOTAL_CNT];
OscillInfo InfoList[MEASURE_TOTAL_CNT];
OscillInfo leftSideInfoList[LEFT_SIDE_ITEM_CNT];
const static char *mesureItemString[MEASURE_TOTAL_CNT] = {"Vpp", "Vmin", "Vmax", "Vrms", "Freq"};
const static void (*measureItemProcessFunc[MEASURE_TOTAL_CNT])(void) = {measureVpp, measureVmin, measureVmax, measureVrms};
const static char *MenuItemStr[MENU_ITEM_CNT] = {"Auto", "Run/Stop", "Measure", "Trigger", "Cursor", "test2", "test3", "test4", "test5"};
static MenuInfo MenuInfoList[MENU_ITEM_CNT];
//字符串数组
const static char *leftSideInfoItemString[LEFT_SIDE_ITEM_CNT] = {"f", "CurA", "CurB", "dx", "1/dx", "CurC", "CurD", "dy"};
// 存放函数指针的数组
const static void (*leftSideItemProcessFunc[LEFT_SIDE_ITEM_CNT])(void *p) = {measureFreq, CurAprocess, CurBprocess, dxProcess, fxProcess, CurCprocess, CurDprocess, dyProcess};

jUnit *j;

/* Private functions ---------------------------------------------------------*/
/**
 * @brief : 左侧光标测量值窗口初始化
 * @param {*}
 * @return {*}
 */
static void leftSideInfoInit(void)
{
    int i;
    for (i = 0; i < LEFT_SIDE_ITEM_CNT; i++)
    {
        leftSideInfoList[i].ID = i;
        leftSideInfoList[i].color = 0xffffff;
        leftSideInfoList[i].isShowed = 0;
        leftSideInfoList[i].str = (char *)leftSideInfoItemString[i];
        leftSideInfoList[i].processFunc = leftSideItemProcessFunc[i];
        leftSideInfoList[i].value = 0;
        leftSideInfoList[i].unit = (char *)malloc(sizeof(char) * 4);
    }
    leftSideInfoList[LEFT_INFO_ID_CURA].color = CursorList[CURSOR_3].color;
    leftSideInfoList[LEFT_INFO_ID_CURB].color = CursorList[CURSOR_4].color;
    leftSideInfoList[LEFT_INFO_ID_CURC].color = CursorList[CURSOR_1].color;
    leftSideInfoList[LEFT_INFO_ID_CURD].color = CursorList[CURSOR_2].color;

    leftSideInfoList[LEFT_INFO_ID_FREQ].isShowed = 1;
    V_setCursorListInfo(leftSideInfoList);
    j = createjUnit("X");
}
/**
 * @brief : 光标对象的初始化
 * @param {*}
 * @return {*}
 */
static void cursorInit(void)
{
    CursorList[CURSOR_1].ID = 0;
    CursorList[CURSOR_1].isVisible = 0;
    CursorList[CURSOR_1].isActive = 0;
    CursorList[CURSOR_1].type = CURSOR_TYPE_X;
    CursorList[CURSOR_1].pos = Y_MIDDEL;
    CursorList[CURSOR_1].color = 0x00FF7F;

    CursorList[CURSOR_2].ID = 1;
    CursorList[CURSOR_2].isVisible = 0;
    CursorList[CURSOR_2].isActive = 0;
    CursorList[CURSOR_2].type = CURSOR_TYPE_X;
    CursorList[CURSOR_2].pos = Y_MIDDEL;
    CursorList[CURSOR_2].color = 0x40E0D0;

    CursorList[CURSOR_3].ID = 2;
    CursorList[CURSOR_3].isVisible = 0;
    CursorList[CURSOR_3].isActive = 0;
    CursorList[CURSOR_3].type = CURSOR_TYPE_Y;
    CursorList[CURSOR_3].pos = X_MIDDEL - 30;
    CursorList[CURSOR_3].color = 0x0000CD;

    CursorList[CURSOR_4].ID = 3;
    CursorList[CURSOR_4].isVisible = 0;
    CursorList[CURSOR_4].isActive = 0;
    CursorList[CURSOR_4].type = CURSOR_TYPE_Y;
    CursorList[CURSOR_4].pos = X_MIDDEL - 30;
    CursorList[CURSOR_4].color = 0x4169E1;

    CursorList[CURSOR_5].ID = 4;
    CursorList[CURSOR_5].isVisible = 0;
    CursorList[CURSOR_5].isActive = 1;
    CursorList[CURSOR_5].type = CURSOR_TYPE_TRIGGER;
    CursorList[CURSOR_5].pos = (int)(Y_MIDDEL - (getOscilTrigVoltage() / currentV_ScareValue) * PIXEL_PER_SCALE);
    CursorList[CURSOR_5].color = 0xffbc00;
}
/**
 * @brief : 菜单项的初始化
 * @param {*}
 * @return {*}
 */
static void menuListInit(void)
{
    int i = 0;
    for (i = 0; i < MENU_ITEM_CNT; i++)
    {
        MenuInfoList[i].ID = i;
        MenuInfoList[i].str = (char *)MenuItemStr[i];
    }
    //MenuInfoList[1].clickedColor = ;
    V_setMenuInfo(MenuInfoList, MENU_ITEM_CNT);
}
/**
 * @brief : 计算vpp
 * @param {*}
 * @return {*}
 */
static void measureVpp(void *p)
{
#ifndef WIN_SIM

    q15_t maxValue;
    q31_t maxValueIndex;
    q15_t minValue;
    q31_t minValueIndex;
#endif // !WIN_SIM

    float Vmax;
    float Vmin;
    float Vpp;
#ifndef WIN_SIM
    arm_max_q15((q15_t*)&validBuffer[trueDataStartPos], samplePerWindow, &maxValue, &maxValueIndex);
    Vmax = ((maxValue - 1653) * getDampFactor() * 3.3f) / ((float)getAmpGain() * 4096.0f);
    arm_min_q15((q15_t*)&validBuffer[trueDataStartPos], samplePerWindow, &minValue, &minValueIndex);
    Vmin = ((minValue - 1653) * getDampFactor() * 3.3f) / ((float)getAmpGain() * 4096.0f);

#endif // !WIN_SIM

    Vpp = fabs(Vmax - Vmin);
    j->unitStr = "V";

    j->value = Vpp;
    j->unitCode = UNIT_NONE;
    autojUnit(j, UNIT_NONE);

    InfoList[VOLTAGE_MEASURE_VPP].value = j->value;
    InfoList[VOLTAGE_MEASURE_VPP].unitCode = j->unitCode;
    strcpy(InfoList[VOLTAGE_MEASURE_VPP].unit, j->unitNewStr);
    printf("Vpp:%f v\n", Vpp);
}
/**
 * @brief : 计算vmin
 * @param {*}
 * @return {*}
 */
static void measureVmin(void *p)
{
#ifndef WIN_SIM

    q15_t minValue;
    q31_t minValueIndex;
    float Vmin;
    arm_min_q15((q15_t *)&validBuffer[trueDataStartPos], samplePerWindow, &minValue, &minValueIndex);
    Vmin = ((minValue - 1653) * getDampFactor() * 3.3f) / ((float)getAmpGain() * 4096.0f);
    j->unitStr = "V";
    if (j->unitNewStr == NULL)
    {
        j->unitNewStr = (char *)malloc(sizeof(char) * 4);
    }
    j->value = Vmin;
    autojUnit(j, UNIT_NONE);
    //Vmin = 1.1261 * Vmin - 0.2176;

    InfoList[VOLTAGE_MEASURE_VMIN].value = j->value;
    strcpy(InfoList[VOLTAGE_MEASURE_VMIN].unit, j->unitNewStr);
    printf("Vmin:%f v\n", Vmin);
#endif
}
/**
 * @brief : 计算出一个窗口内的电压最大值，并直接将计算的数据放入infolist中
 * @param {*}
 * @return {*}
 */
static void measureVmax(void *p)
{
#ifndef WIN_SIM

    q15_t maxValue;
    q31_t maxValueIndex;
    float Vmax;
    arm_max_q15((q15_t *)&validBuffer[trueDataStartPos], samplePerWindow, &maxValue, &maxValueIndex);
    Vmax = ((maxValue - 1653) * getDampFactor() * 3.3f) / ((float)getAmpGain() * 4096.0f);
    j->unitStr = "V";
    j->value = Vmax;
    autojUnit(j, UNIT_NONE);

    //2v档测试
    //Vmax = 1.1261 * Vmax - 0.2176;
    InfoList[VOLTAGE_MEASURE_VMAX].value = j->value;
    strcpy(InfoList[VOLTAGE_MEASURE_VMAX].unit, j->unitNewStr);
    printf("Vmax:%f v\n", Vmax);
#endif
}
/**
 * @brief : 计算vrms
 * @param {*}
 * @return {*}
 */
static void measureVrms(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
}
/**
 * @brief : 计算频率
 * @param {*}
 * @return {*}
 */
static void measureFreq(void *p)
{
    OscillInfo *list = (OscillInfo *)p;

    list[LEFT_INFO_ID_FREQ].value = InfoList[TIME_MEASURE_FREQ].value;
    list[LEFT_INFO_ID_FREQ].unit = InfoList[TIME_MEASURE_FREQ].unit;
}
/**
 * @brief : 光标A数值更新
 * @param {*}
 * @return {*}
 */
static void CurAprocess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->unitStr = "S";
    j->value = CursorList[CURSOR_3].measureValue;
    autojUnit(j, UNIN_NANO);
    list[LEFT_INFO_ID_CURA].value = j->value;
    list[LEFT_INFO_ID_CURA].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_CURA].unit, j->unitNewStr);
}
/**
 * @brief : 光标B数值更新
 * @param {*}
 * @return {*}
 */
static void CurBprocess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->unitStr = "S";
    j->value = CursorList[CURSOR_4].measureValue;
    autojUnit(j, UNIN_NANO);

    list[LEFT_INFO_ID_CURB].value = j->value;
    list[LEFT_INFO_ID_CURB].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_CURB].unit, j->unitNewStr);
}
/**
 * @brief : 两个x类型的光标的差值,即电压差
 * @param {*}
 * @return {*}
 */
static void dyProcess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->unitStr = "V";
    j->value = leftSideInfoList[LEFT_INFO_ID_CURC].value - leftSideInfoList[LEFT_INFO_ID_CURD].value;
    autojUnit(j, leftSideInfoList[LEFT_INFO_ID_CURC].unitCode);

    list[LEFT_INFO_ID_DY].value = j->value;
    list[LEFT_INFO_ID_DY].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_DY].unit, j->unitNewStr);
}
/**
 * @brief : 两个y类型的光标之间的频率
 * @param {*}
 * @return {*}
 */
static void fxProcess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->unitStr = "Hz";
    j->value = 1.0f / leftSideInfoList[LEFT_INFO_ID_DX].value;
    autojUnit(j, -leftSideInfoList[LEFT_INFO_ID_DX].unitCode);
    //list[LEFT_INFO_ID_FX].value = 1.0f / leftSideInfoList[LEFT_INFO_ID_DX].value;
    list[LEFT_INFO_ID_FX].value = fabs(j->value);
    strcpy(list[LEFT_INFO_ID_FX].unit, j->unitNewStr);
}
/**
 * @brief : 光标C数值更新
 * @param {*}
 * @return {*}
 */
static void CurCprocess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->value = CursorList[CURSOR_1].measureValue;
    j->unitStr = "V";
    autojUnit(j, UNIT_NONE);
    list[LEFT_INFO_ID_CURC].value = j->value;
    list[LEFT_INFO_ID_CURC].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_CURC].unit, j->unitNewStr);
}
/**
 * @brief : 光标D数值更新
 * @param {*}
 * @return {*}
 */
static void CurDprocess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    j->value = CursorList[CURSOR_2].measureValue;
    j->unitStr = "V";
    autojUnit(j, UNIT_NONE);

    list[LEFT_INFO_ID_CURD].value = j->value;
    list[LEFT_INFO_ID_CURD].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_CURD].unit, j->unitNewStr);
}

/**
 * @brief : 两个y类型的光标之间的时间差值，即时长,原始单位是ns
 * @param {*}
 * @return {*}
 */
static void dxProcess(void *p)
{
    OscillInfo *list = (OscillInfo *)p;
    list[LEFT_INFO_ID_DX].value = CursorList[CURSOR_3].measureValue - CursorList[CURSOR_4].measureValue;
    j->value = list[LEFT_INFO_ID_DX].value;
    j->unitStr = "S";
    autojUnit(j, UNIN_NANO);
    list[LEFT_INFO_ID_DX].value = (float)j->value;
    list[LEFT_INFO_ID_DX].unitCode = j->unitCode;
    strcpy(list[LEFT_INFO_ID_DX].unit, j->unitNewStr);
}
/**
 * @brief : 测量参数数组的初始化
 * @param {*}
 * @return {*}
 */
static void infoListInit(void)
{
    int i = 0;
    for (i = 0; i < INFO_LIST_CNT; i++)
    {
        InfoList[i].ID = i;
        InfoList[i].isShowed = 0;
        InfoList[i].str = (char *)mesureItemString[i];
        InfoList[i].processFunc = measureItemProcessFunc[i];
        InfoList[i].color = GUI_WHITE;
        InfoList[i].value = 0;
        InfoList[i].unit = (char *)malloc(sizeof(char) * 4);
    }

    V_setOscillDataList(InfoList);
}
/**
 * @brief : 注册示波器按键映射
 * @param {*}
 * @return {*}
 */
void registerOscillButton()
{
    setEncoder1Listener(onEncoderV_ScaleRotated);
    setEncoder2Listener(onEncoderH_ScaleRotated);
    setEncoder3Listener(onCursorRotated);
    setEncoder4Listener(onEncoderV_PosRotated);
    setEncoder5Listener(onEncoderH_PosRotated);
    setEncoder6Listener(onTriggerRotated);

    setEncoder5ButListener(onH_Pos_Reset);
    setEncoder4ButListener(onV_Pos_Reset);
    setEncoder6ButListener(onTriggerReset);

    setF1ButtonListener(onF1ButtonClicked);
    setF2ButtonListener(onF2ButtonClicked);
    setF3ButtonListener(onF3ButtonClicked);
    setF4ButtonListener(onF4ButtonClicked);
    setF5ButtonListener(onF5ButtonClicked);
    keyState = 1;
}
/**
 * @brief : 取消示波器按键映射
 * @param {*}
 * @return {*}
 */
void cancelOscillButton()
{
    setEncoder1Listener(NULL);
    setEncoder2Listener(NULL);
    setEncoder3Listener(NULL);
    setEncoder4Listener(NULL);
    setEncoder5Listener(NULL);
    setEncoder6Listener(NULL);

    setEncoder5ButListener(NULL);
    setEncoder4ButListener(NULL);
    setEncoder6ButListener(NULL);

    setF1ButtonListener(NULL);
    setF2ButtonListener(NULL);
    setF3ButtonListener(NULL);
    setF4ButtonListener(NULL);
    setF5ButtonListener(NULL);
    keyState = 0;
}
/**
 * @brief : 示波器系统初始化
 * @param {*}
 * @return {*}
 */
void Oscil_Init(void)
{
    int i;
    timer = rt_timer_create("oneSecond",
                            oneSecondTimerCallback,
                            NULL,
                            1000,
                            RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_PERIODIC);
    rt_timer_start(timer);

    My_DAC_Init();
    DSP_Init();
    ADC_Condition_Init();
    menuListInit();
    infoListInit();
    cursorInit();
    leftSideInfoInit();
    V_setCursor(CursorList);

    setBufferCount(1);
    setValidBuffer((uint16_t *)validBuffer, StorageDepth);
    setADC_Buffer(BUFFER_0, (uint32_t)buffer0, StorageDepth / 2);

    for (i = 0; i < ADC_DMA_BUFFER_SIZE * 2; i++)
    {
        triggerBuffer[i] = 0;
    }
    setTriggerCounter(&Counter);
    setTriggerBuffer((uint32_t)triggerBuffer, ADC_DMA_BUFFER_SIZE * 2);
    //ADC初始化
    My_ADC_init(0);
    V_setTriggerState(TRIGGER_STATE_AUTO);
    //设置开机初始量程
    setOscilV_Scale(V_SCALE_2V);
    setOscilH_Scale(H_SCALE_50US);
    //设置初始触发方式，上升沿触发
    setOscilTrigType(TRIG_TYPE_FALLING);
    //设置初始触发电压
    setOscilTrigVoltage(0);
    //设置显示缓存
    V_setGraph(&displayData[0], ADC_DMA_BUFFER_SIZE * 2);
    //初始化显示界面
    V_OscillUI_Init();
    //只有连接了按键模块才注册按键，否则会出错
    if (getModuleState(MODULE_KEYBOARD))
    {
        registerOscillButton();
    }
}

#define K (4096.0f / 3.3f)

#define PI (3.1415926f)
/**
 * @brief : 测量电压系列数据的计算和处理，可单独用一个线程运行
 * @param {*}
 * @return {*}
 */
void voltageMeasureProcess(void)
{
    int i;
    for (i = 0; i < INFO_LIST_CNT; i++)
    {
        if (InfoList[i].isShowed && InfoList[i].processFunc != NULL)
        {
            (*(InfoList[i].processFunc))(InfoList);
        }
    }
}
/**
 * @brief : 左侧信息框数据的处理，需要及时更新
 * @param {*}
 * @return {*}
 */
void leftSideInfoProcess(void)
{
    int i;
    for (i = 0; i < LEFT_SIDE_ITEM_CNT; i++)
    {
        if (leftSideInfoList[i].isShowed && leftSideInfoList[i].processFunc != NULL)
        {
            (*(leftSideInfoList[i].processFunc))(leftSideInfoList);
        }
    }
}
/**
 * @brief : 根据当前时基计算一些参数，只在切换时基时计算一次
 * @param {*}
 * @return {*}
 * 计算的参数：
 * 有效数据的总时长，单位us
 * 显示区域的总时长，单位ns
 * 显示一个屏幕的波形需要用到的采样点个数，单位个
 */
static void dataProcess2(void)
{
    if (getSampleState() != ADC_STATE_HOLD)
    {
        //有效数据总时长,单位us
        //printf("new one\n");
        validDataDuration = (int)((float)((float)StorageDepth / (float)getCurrentADCSamplingRateValue()) * 1000000);
    }
    else
    {
        //printf("last one\n");
        validDataDuration = (int)((float)((float)StorageDepth / (float)getLastADCSamplingRateValue()) * 1000000);
    }

    //显示区域总时长，单位ns
    displayDataDuration = currentH_ScareValue * 10;
    //二者之比
    _k = (float)displayDataDuration / ((float)validDataDuration * 1000.0f);
    V_setWaveWinInfo(_k, 0);
    //printf("k:%f\n", _k);
    if (getSampleState() != ADC_STATE_HOLD)
    {
        samplePerWindow = (uint32_t)((float)getCurrentADCSamplingRateValue() * (float)((float)displayDataDuration / 1000000000.0f));
    }
    else
    {
        samplePerWindow = (uint32_t)((float)getLastADCSamplingRateValue() * (float)((float)displayDataDuration / 1000000000.0f));
    }
    //printf("samplePerWindow:%d\n", samplePerWindow);
}
#ifdef WIN_SIM
static void waveDataProcess(void){
        float value;
        //输入进显存
        for (int l = 0; l < METER_WINDOW_WIDTH; l++)
        {
            value = (((rand()%(4096-1+1)+1 - 1653) * getDampFactor() * 3.3f) / (getAmpGain() * 4096 * currentV_ScareValue));
            displayData[l].y = (int)(Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * value));
            displayData[l].x = l;
            //printf("%d\n", tmp[l]);
        }

}

#else
/**
 * @brief : 波形数据处理函数，用于将采集到的数据处理并给view显示
 * @param {*}
 * @return {*}
 */
static void waveDataProcess(void)
{

    int i;

    //波形缩放系数
    float offset = (float)samplePerWindow / ((float)METER_WINDOW_WIDTH);
    //从第几个触发点开始显示
    int startTriPoint = (int)((float)getTriggerEventCnt() * triggerPercent);
    //test:
    //offset = 0;
    //printf("***total event cnt :%d\n", getTriggerEventCnt());
    //printf("startTriPoint :%d\n", startTriPoint);
//在连接了前端调理电路时
#ifndef NO_CONDI_BOARD
    float value;
    uint16_t dataIndex;

    if (TriggerState == TRIGGER_STATE_TRIGGERED)
    {
        trueDataStartPos = (int)(triggerBuffer[startTriPoint] * 2 - currentH_Pos * offset - (METER_WINDOW_WIDTH / 2) * offset);
    }
    else
    {
        trueDataStartPos = (int)(StorageDepth / 2 - currentH_Pos * offset - (METER_WINDOW_WIDTH / 2) * offset);
    }
    //使用等比例缩小,缩小的算法是直接等距离抽取一定的点，这样不需要额外的运算
    if (samplePerWindow >= METER_WINDOW_WIDTH)
    {

        for (i = 0; i < ValidDataSize; i++)
        {
            if (i > 740)
                break;

            //从哪一位数据开始显示,
            dataIndex = i * offset + trueDataStartPos;
            value = (((validBuffer[dataIndex] - 1653) * getDampFactor() * 3.3f) / (getAmpGain() * 4096 * currentV_ScareValue));

            displayData[i].y = Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * value);
            displayData[i].x = i;
            //printf("%d\n", displayData[i].y );
        }
    }
    //使用内插
    else
    {
        uint16_t tmp[METER_WINDOW_WIDTH];
        //q15_t tmp2[METER_WINDOW_WIDTH];
        //q15_t tmp3[METER_WINDOW_WIDTH];
        int l = 0;
#ifdef USE_SINC
        //在采样点数大于36个时使用线性内插，小于等于36个时再使用sinc内插，防止计算时间过长
        if (samplePerWindow > 36)
        {
            Linear_Interpolation(&validBuffer[trueDataStartPos], samplePerWindow, tmp, METER_WINDOW_WIDTH);
        }
        else
        {
            Sinc_Interpolation(&validBuffer[trueDataStartPos], samplePerWindow, tmp, METER_WINDOW_WIDTH);
        }
#else
        Linear_Interpolation(&validBuffer[trueDataStartPos], samplePerWindow, tmp, METER_WINDOW_WIDTH);

#endif // DEBUG
        float value;
        //输入进显存
        for (l = 0; l < METER_WINDOW_WIDTH; l++)
        {
            value = (((tmp[l] - 1653) * getDampFactor() * 3.3f) / (getAmpGain() * 4096 * currentV_ScareValue));
            displayData[l].y = (int)(Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * value));
            displayData[l].x = l;
            //printf("%d\n", tmp[l]);
        }
    }

//在未连接前端调理电路时
#else
    if (RuningState != STATE_HOLD)
    {
        for (i = 0; i < ValidDataSize - currentH_Pos; i++)
        {

            if (i > 740)
                break;

            //
            if (samplePerWindow >= 720)
            {
                displayData2[i] = Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * ((validBuffer[i * offset + currentH_Pos] * 3.3f) / (4096 * currentV_ScareValue)));
                displayData[i].y = Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * ((validBuffer[i * offset + currentH_Pos] * 3.3f) / (4096 * currentV_ScareValue)));
                displayData[i].x = i;
            }
            //使用插值补足
            else
            {
                Linear_Interpolation(validBuffer, samplePerWindow, validBuffer2, 720);
                displayData[i].y = Y_MIDDEL - currentV_Pos - (PIXEL_PER_SCALE * ((validBuffer2[i + currentH_Pos] * 3.3f) / (4096 * currentV_ScareValue)));
                displayData[i].x = i;
            }
        }
    }
#endif // !NO_CONDI_BOARD
}
#endif
#define INFO_DATA_PROCESS_TICK 3
/**
 * @brief : 示波器主要更新线程,更新速率由main函数设置
 * @param {*}
 * @return {*}
 */
void oscillLooper(void)
{
    static uint8_t otherTime = 0;
    leftSideInfoProcess();
    if (getModuleState(MODULE_KEYBOARD) && keyState == 0)
    {
        registerOscillButton();
    }
    //如果adc正在采样则不更新数据
    if (getSampleState() == ADC_STATE_SAMPLING)
        return;
    waveDataProcess();
    //每3次tick更新一次测量数据，防止卡顿
    if (otherTime == INFO_DATA_PROCESS_TICK)
    {
        voltageMeasureProcess();

        otherTime = 0;
    }
    else
    {
        otherTime++;
    }
    //如果hold开启，就不继续采集数据
    if (getSampleState() != ADC_STATE_HOLD)
    {
        measureFreqProcess();
        resumeADC_Sampling();
    }
}
/**
 * @brief : 打开示波器模块
 * @param {*}
 * @return {*}
 */
void openOscil(void)
{
    Oscil_Init();
}
/**
 * @brief : 关闭示波器模块，回到multimeter主界面
 * @param {*}
 * @return {*}
 */
void closeOscil(void)
{
    rt_timer_delete(timer);
    cancelOscillButton();
    closeADC();
}
/**
 * @brief : 获取电压系列测量数值
 * @param {uint8_t} measureType
 * @return {*}
 */
float getVoltageMeasure(uint8_t measureType)
{
    switch (measureType)
    {
    case VOLTAGE_MEASURE_VPP:
        /* code */
        return InfoList[VOLTAGE_MEASURE_VPP].value;
        break;

    default:
        break;
    }
}
/**
 * @brief : 获取时间系列测量数值
 * @param {uint8_t} measureType
 * @return {*}
 */
float getTimeMeasure(uint8_t measureType) {}
/**
 * @brief : 设置示波器水平刻度
 * @param {uint8_t} scale
 * @return {*}
 */
void setOscilH_Scale(uint8_t scale)
{
    //pauseADC_Sampling();
    switch (scale)
    {
    case H_SCALE_5NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
        #ifndef WIN_SIM

        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);
        #endif
        //setStorageDepth();
        //SamplingRate = 7200000;
        currentH_ScareValue = 5;
        V_setH_Scale("Time: 5ns");
        break;

    case H_SCALE_10NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        //SamplingRate = 7200000;
        currentH_ScareValue = 10;
        V_setH_Scale("Time: 10ns");
        break;
    case H_SCALE_20NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        //SamplingRate = 7200000;
        currentH_ScareValue = 20;
        V_setH_Scale("Time: 20ns");
        break;
    case H_SCALE_50NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        //SamplingRate = 7200000;
        currentH_ScareValue = 50;
        V_setH_Scale("Time: 50ns");
        break;
    /**********再往上的时基无效，采样率已经不够用了**********/
    case H_SCALE_100NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 100;
        V_setH_Scale("Time: 100ns");
        break;

    case H_SCALE_200NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 200;
        V_setH_Scale("Time: 200ns");
        break;
    case H_SCALE_500NS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 500;
        V_setH_Scale("Time: 500ns");
        break;
    case H_SCALE_1US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 1000;
        V_setH_Scale("Time: 1us");
        break;
    case H_SCALE_2US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 2000;
        V_setH_Scale("Time: 2us");
        break;
    case H_SCALE_5US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 5000;
        V_setH_Scale("Time: 5us");
        break;
    case H_SCALE_10US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //SamplingRate = 7200000;
        currentH_ScareValue = 10000;
        V_setH_Scale("Time: 10us");
        break;
    case H_SCALE_20US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 7200000;
        currentH_ScareValue = 20000;
        V_setH_Scale("Time: 20us");
        break;
    case H_SCALE_50US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 7200000;
        currentH_ScareValue = 50000;
        V_setH_Scale("Time: 50us");
        break;

    //从这里开始采样率开始从最高往下降
    case H_SCALE_100US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div4);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div4, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 3600000;
        currentH_ScareValue = 100000;
        V_setH_Scale("Time: 100us");
        break;
    case H_SCALE_200US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div8);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_3Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 1800000;
        currentH_ScareValue = 200000;
        V_setH_Scale("Time: 200us");
        break;

    case H_SCALE_500US:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_56Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_56Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //SamplingRate = 620689;
        currentH_ScareValue = 500000;
        V_setH_Scale("Time: 500us");
        break;

    case H_SCALE_1MS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_112Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_112Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //315.7894737
        //SamplingRate = 315789;
        currentH_ScareValue = 1000000;
        V_setH_Scale("Time: 1ms");
        break;
    case H_SCALE_2MS:
        /* code */
        //157.8947368
        //setADC_Prescaler(ADC_Prescaler_Div4);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_112Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div4, ADC_SampleTime_112Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //SamplingRate = 157894;
        currentH_ScareValue = 2000000;
        V_setH_Scale("Time: 2ms");
        break;
    case H_SCALE_5MS:
        /* code */
        //74.68879668
        //setADC_Prescaler(ADC_Prescaler_Div2);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div2, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //SamplingRate = 74688;
        currentH_ScareValue = 5000000;
        V_setH_Scale("Time: 5ms");
        break;
    case H_SCALE_10MS:
        /* code */
        //37.34439834
        //setADC_Prescaler(ADC_Prescaler_Div4);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div4, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //SamplingRate = 37344;
        currentH_ScareValue = 10000000;
        V_setH_Scale("Time: 10ms");
        break;
    case H_SCALE_20MS:
        /* code */
        //18.67219917
        //setADC_Prescaler(ADC_Prescaler_Div8);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(28800);
        //setStorageDepth(7200);

        //SamplingRate = 18672;
        currentH_ScareValue = 20000000;
        V_setH_Scale("Time: 20ms");
        break;

    case H_SCALE_50MS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div8);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 18672;
        currentH_ScareValue = 50000000;
        V_setH_Scale("Time: 50ms");
        break;
    case H_SCALE_100MS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div8);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 18672;
        currentH_ScareValue = 100000000;
        V_setH_Scale("Time: 100ms");
        break;
    case H_SCALE_200MS:
        /* code */
        //setADC_Prescaler(ADC_Prescaler_Div8);
        //setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_480Cycles);
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 18672;
        currentH_ScareValue = 200000000;
        V_setH_Scale("Time: 200ms");
        break;
    //再往下的时基不能再使用常规的方法获取，否则会导致等待时间过长，应采用其他方式
    case H_SCALE_500MS:
        /* code */
        // setADC_Prescaler(ADC_Prescaler_Div2);
        // setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);

        break;
    case H_SCALE_1S:
        /* code */
        // setADC_Prescaler(ADC_Prescaler_Div2);
        // setAll_ADC_SamplingTime(ADC_CHANNEL, ADC_SampleTime_3Cycles);

    default:
#ifndef WIN_SIM
        setAll_ADC_SampTimeAndPrescale(ADC_Prescaler_Div8, ADC_SampleTime_480Cycles);

#endif

        setStorageDepth(57600);
        //setStorageDepth(7200);

        //SamplingRate = 18672;
        currentH_ScareValue = 50000000;
        V_setH_Scale("Time: 50ms");
        break;
    }
    currentH_Scare = scale;

    dataProcess2();
    cursorUpdate(CursorList);
    //printf("current scale:%d\n", scale);
}
/**
 * @brief : 设置示波器垂直刻度
 * @param {uint8_t} scale
 * @return {*}
 */
void setOscilV_Scale(uint8_t scale)
{
    switch (scale)
    {
    case V_SCALE_5V: //范围+-15v ,衰减0.1
        setDampFactor(DAMPING_FACTOR_10);
        setAmpGain(VERTI_GAIN_1);
        V_setV_Scale("CH1: 5V");
        currentV_ScareValue = 5.0f;
        /* code */
        break;
    case V_SCALE_2V: //+-6v  0.2
        /* code */
        setDampFactor(DAMPING_FACTOR_10);
        setAmpGain(VERTI_GAIN_2);
        V_setV_Scale("CH1: 2V");
        currentV_ScareValue = 2.0f;
        break;
    case V_SCALE_1V: //+-3v 0.55
        /* code */
        setDampFactor(DAMPING_FACTOR_10);
        setAmpGain(VERTI_GAIN_5);
        V_setV_Scale("CH1: 1V");
        currentV_ScareValue = 1.0f;
        break;
    case V_SCALE_500mV: //+-1.5v  1.1
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_1);
        V_setV_Scale("CH1: 500mV");
        currentV_ScareValue = 0.5f;
        break;
    case V_SCALE_200mV: //+-600mV 2.75
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_2);
        V_setV_Scale("CH1: 200mV");
        currentV_ScareValue = 0.2f;
        break;
    case V_SCALE_100mV: //+-300mV  5.5
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_5);
        V_setV_Scale("CH1: 100mV");
        currentV_ScareValue = 0.1f;
        break;
    case V_SCALE_50mV: //+-150mv  11
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_10);
        V_setV_Scale("CH1: 50mV");
        currentV_ScareValue = 0.05f;
        break;
    case V_SCALE_20mV: //+=60mv 27.5
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_20);
        V_setV_Scale("CH1: 20mV");
        currentV_ScareValue = 0.02f;
        break;
    case V_SCALE_10mV: //+-30mv 55
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_50);
        V_setV_Scale("CH1: 10mV");
        currentV_ScareValue = 0.01f;
        break;

        //最小
    case V_SCALE_5mV: //+-15mv 110
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_100);
        V_setV_Scale("CH1: 5mV");
        currentV_ScareValue = 0.005f;
        break;
    case V_SCALE_2mV: //+-6mv 275
        /* code */
        setDampFactor(DAMPING_FACTOR_1);
        setAmpGain(VERTI_GAIN_200);
        V_setV_Scale("CH1: 2mV");
        currentV_ScareValue = 0.002f;
        break;
    default:
        //默认最大量程
        setDampFactor(DAMPING_FACTOR_10);
        setAmpGain(VERTI_GAIN_1);
        V_setV_Scale("CH1: 5V");
        currentV_ScareValue = 5.0f;
        break;
    }
    currentV_Scare = scale;
    //在垂直时基变化后，触发电压会被重置为0，方便重新设置触发
    setOscilTrigVoltage(0);
    cursorUpdate(CursorList);
}
/**
 * @brief : 设置水平偏移，使用正坐标系
 * @param {int} pos 要偏移的像素
 * @return {*}
 */
void setOscilH_Pos(int pos)
{
    currentH_Pos = pos;
}
/**
 * @brief : 设置垂直偏移，使用正坐标系
 * @param {int} pos 要偏移的像素
 * @return {*}
 */
void setOscilV_Pos(int pos)
{
    currentV_Pos = pos;
}
/**
 * @brief : 获取水平偏移，使用正坐标系
 * @param {*}
 * @return {*}
 */
int getOscilH_Pos(void)
{
    return currentH_Pos;
}
/**
 * @brief : 获取垂直偏移，使用正坐标系
 * @param {*}
 * @return {*}
 */
int getOscilV_Pos(void)
{
    return currentV_Pos;
}
/**
 * @brief : 获取当前示波器的触发方式
 * @param {*}
 * @return {*}
 */
uint8_t getOscilTrigType(void)
{
    return TrigType;
}
/**
 * @brief : 设置触发方式
 * @param {uint8_t} type
 * @return {*}
 */
void setOscilTrigType(uint8_t type)
{
    TrigType = type;
    setADCTrigType(type);
    V_setTrigger(type, getTrigVoltage());
}
/**
 * @brief : 获取当前垂直时基下的触发电压
 * @param {*}
 * @return {*}
 */
float getOscilTrigVoltage(void)
{
    return TrigVoltage;
}
/**
 * @brief : 设置当前垂直时基下的触发电压，可以为负值
 * @param {float} voltage
 * @return {*}
 */
void setOscilTrigVoltage(float voltage)
{
    TrigVoltage = voltage;
    setTrigVoltage(getActualTrigVoltage(voltage));
    V_setTrigger(getOscilTrigType(), voltage);
}
/**
 * @brief : 获得当前水平时基
 * @param {*}
 * @return {uint8_t} 水平时基宏
 */
uint8_t getOscilHoriScale()
{
    return currentH_Scare;
}
/**
 * @brief : 获得当前垂直时基
 * @param {*}
 * @return {uint8_t} 垂直时基宏
 */
uint8_t getOscilVertiScale()
{
    return currentV_Scare;
}
/**
 * @brief : 设置光标x坐标
 * @param {uint8_t} which
 * @param {uint16_t} posX
 * @return {*}
 */
void setCursorPos(uint8_t which, uint16_t posX)
{

    CursorList[which].pos = posX;
}
/**
 * @brief : 获取当前光标
 * @param {uint8_t} which
 * @return {*}
 */
uint16_t getCursorPos(uint8_t which)
{
    return CursorList[which].pos;
}
/**
 * @brief : 获取当前光标所测值
 * @param {uint8_t} which
 * @param {uint16_t} posX
 * @return {*}
 */
float getValueByCursor(uint8_t which, uint16_t posX)
{
    float value;
    if (which == CURSOR_1 || which == CURSOR_2)
    {
    }
    else
    {
        //return cursor2_Pos_X;
    }
}

/**
 * @brief : 设置运行状态（hold功能）
 * @param {uint8_t} state
 * @return {*}
 */
void setRunningState(uint8_t state)
{
    RuningState = state;
    V_setState(state);
}
/**
 * @brief : hold功能
 * @param {*}
 * @return {*}
 */
void holdTrigger(void)
{
    if (RuningState == STATE_RUNNING)
    {
        setRunningState(STATE_HOLD);
        setHoldState(ADC_STATE_HOLD);
        MenuInfoList[1].unClickedColor = 0xDC143C;
    }
    else
    {

        setRunningState(STATE_RUNNING);
        setHoldState(ADC_STATE_SAMPLING);
        MenuInfoList[1].unClickedColor = 0xB6B6AA;

        dataProcess2();
    }
}
/**
 * @brief : 获取当前运行状态
 * @param {*}
 * @return {*}
 */
uint8_t getRunningState(void)
{
    return RuningState;
}
/**
 * @brief : 显示光标
 * @param {unsignedchar} which
 * @return {*}
 */
void showCursor(unsigned char which)
{
}
/**
 * @brief : 关闭光标
 * @param {unsignedchar} which
 * @return {*}
 */
void hideCursor(unsigned char which)
{
}
/**
 * @brief : 设置存储深度
 * @param {uint32_t} depth 单位pts 如果超过最大存储深度，则自动设置为最大存储深度
 * @return {*}
 */
void setStorageDepth(uint32_t depth)
{
    if (depth > ADC_DMA_BUFFER_SIZE)
    {
        setValidBuffer((uint16_t *)validBuffer, ADC_DMA_BUFFER_SIZE);
        changeADCBufferSize(ADC_DMA_BUFFER_SIZE / 2);
        StorageDepth = ADC_DMA_BUFFER_SIZE;
    }
    else
    {
        setValidBuffer((uint16_t *)validBuffer, depth);
        changeADCBufferSize(depth / 2);
        StorageDepth = depth;
    }
}
/**
 * @brief : 获取当前所使用的存储深度
 * @param {*}
 * @return {uint32_t} 单位pts
 */
uint32_t getStorageDepth(void)
{
    return StorageDepth;
}
/**
 * @brief : 根据信号的特征自动调整垂直和水平时基，此过程会耗时
 * @param {*}
 * @return {*}
 */
void autoMeasure(void)
{
}
/**
 * @brief : 获取当前触发状态
 * @param {*}
 * @return {*}
 */
uint8_t getTriggerState(void)
{
    return TriggerState;
}
/**
 * @brief : 测量数据处理
 * @param {*}
 * @return {*}
 */
void measureFreqProcess(void)
{
    if (infoListTmp[TIME_MEASURE_FREQ] > 5)
    {
        TriggerState = TRIGGER_STATE_TRIGGERED;
        V_setTriggerState(TRIGGER_STATE_TRIGGERED);

        if (infoListTmp[TIME_MEASURE_FREQ] <= 999)
        {
            InfoList[TIME_MEASURE_FREQ].value = infoListTmp[TIME_MEASURE_FREQ];
            InfoList[TIME_MEASURE_FREQ].unit = "Hz";
        }
        else if (infoListTmp[TIME_MEASURE_FREQ] > 999)
        {
            InfoList[TIME_MEASURE_FREQ].value = (float)infoListTmp[TIME_MEASURE_FREQ] / 1000.0f;
            InfoList[TIME_MEASURE_FREQ].unit = "KHz";
        }
        else if (infoListTmp[TIME_MEASURE_FREQ] > 999999)
        {
            /* code */
            InfoList[TIME_MEASURE_FREQ].value = (float)infoListTmp[TIME_MEASURE_FREQ] / 1000000.0f;
            InfoList[TIME_MEASURE_FREQ].unit = "MHz";
        }
    }
    else
    {
        TriggerState = TRIGGER_STATE_AUTO;
        V_setTriggerState(TRIGGER_STATE_AUTO);
        InfoList[TIME_MEASURE_FREQ].value = 0;
    }
}
/**
 * @brief : 定时器定时1秒，会周期性调用此函数，用于测量信号频率及其他参数
 * @param {*}
 * @return {*}
 * 此函数由硬件中断调用，不能在此函数内执行耗时操作
 */
static void oneSecondTimerCallback(void)
{
    static uint16_t lastTrigPos;
    static uint8_t otherTime = 0;
    infoListTmp[TIME_MEASURE_FREQ] = Counter;
    printf("hz:%d\n", Counter);
    Counter = 0;

    //3秒后隐藏触发电压指示线
    if (otherTime == 2)
    {

        if (lastTrigPos == currentTrigLinePos)
        {
            CursorList[CURSOR_5].isVisible = 0;
        }
        else
        {
            CursorList[CURSOR_5].isVisible = 1;
        }
        lastTrigPos = currentTrigLinePos;
        otherTime = 0;
    }
    else
    {
        otherTime++;
    }
}
/**************以下皆为按键及旋钮监听函数***************************/

/**
 * @brief : 垂直缩放旋钮监听
 * @param {*}
 * @return {*}
 */
static void onEncoderV_ScaleRotated(uint8_t dir)
{
    if (dir == ENCODER_CCW)
    {
        if (getOscilVertiScale() < V_SCALE_5V)
        {
            setOscilV_Scale(getOscilVertiScale() + 1);
        }
        else
        {
            beeperTrigger(BEEPER_WARNING);
        }
    }
    else
    {
        if (getOscilVertiScale() > V_SCALE_2mV)
        {
            setOscilV_Scale(getOscilVertiScale() - 1);
        }
        else
        {
            beeperTrigger(BEEPER_WARNING);
        }
    }
}
/**
 * @brief : 水平缩放旋钮监听
 * @param {*}
 * @return {*}
 */
static void onEncoderH_ScaleRotated(uint8_t dir)
{
    if (dir == ENCODER_CW)
    {
        if (getOscilHoriScale() > H_SCALE_100NS)
        {
            setOscilH_Scale(getOscilHoriScale() - 1);
        }
        else
        {
            beeperTrigger(BEEPER_WARNING);
        }
    }
    else
    {
        if (getOscilHoriScale() < H_SCALE_200MS)
        {
            setOscilH_Scale(getOscilHoriScale() + 1);
        }
        else
        {
            beeperTrigger(BEEPER_WARNING);
        }
    }
}
/**
 * @brief : 光标数值更新，当切换垂直时基和水平时基时需要调用
 * @param {*}
 * @return {*}
 */
static void cursorUpdate(Cursor *list)
{
    int i;
    for (i = 0; i < 4; i++)
    {
        if (list[i].type == CURSOR_TYPE_X)
        {
            list[i].measureValue = ((float)(Y_MIDDEL - list[i].pos) / (float)PIXEL_PER_SCALE) * currentV_ScareValue;
            list[i].measureUnit = "V";
        }
        else if (list[i].type == CURSOR_TYPE_Y)
        {
            list[i].measureValue = ((float)(list[i].pos - X_MIDDEL + 30) / (float)PIXEL_PER_SCALE) * currentH_ScareValue;
            list[i].measureUnit = "ns";
        }
    }
}

#define PIXEL_PER_TICK 2

/**
 * @brief : 改变光标位置监听函数
 * @param {*}
 * @return {*}
 */
static void onCursorRotated(uint8_t dir)
{

    int i;
    for (i = 0; i < 4; i++)
    {
        if (CursorList[i].isActive == 1 && CursorList[i].isVisible == 1)
        {

            if (dir == ENCODER_CW)
            {

                if (CursorList[i].type == CURSOR_TYPE_X)
                {
                    CursorList[i].pos -= PIXEL_PER_TICK;
                }
                else if (CursorList[i].type == CURSOR_TYPE_Y)
                {
                    CursorList[i].pos += PIXEL_PER_TICK;
                }
            }
            else
            {
                if (CursorList[i].type == CURSOR_TYPE_X)
                {
                    CursorList[i].pos += PIXEL_PER_TICK;
                }
                else if (CursorList[i].type == CURSOR_TYPE_Y)
                {
                    CursorList[i].pos -= PIXEL_PER_TICK;
                }
            }
            cursorUpdate(CursorList);
        }
    }
}
/**
 * @brief : 根据所给信息计算出波形指示窗口的矩形框偏移
 * @param {uint16_t} samplePerWindow 
 * @param {int} currentH_Pos
 * @param {uint32_t} storageDepth
 * @return {int} 偏移
 */
static int getWaveWinPos(uint16_t samplePerWindow, int currentH_Pos, uint32_t storageDepth)
{
    float offset = (float)samplePerWindow / ((float)METER_WINDOW_WIDTH);
    int pos;
    pos = -(int)((currentH_Pos * offset * TOP_WAVE_WIN_WIDTH) / storageDepth);
    return pos;
}
/**
 * @brief : 水平位置偏移旋钮监听
 * @param {*}
 * @return {*}
 */
static void onEncoderH_PosRotated(uint8_t dir)
{
    if (dir == ENCODER_CW)
    {
        currentH_Pos += 10;
    }
    else
    {
        currentH_Pos -= 10;
    }
    V_setH_arrowPos(currentH_Pos);
    V_setWaveWinInfo(_k, getWaveWinPos(samplePerWindow, currentH_Pos, getStorageDepth()));
}
/**
 * @brief : 垂直偏移旋钮监听
 * @param {*}
 * @return {*}
 */
static void onEncoderV_PosRotated(uint8_t dir)
{
    if (dir == ENCODER_CW)
    {
        currentV_Pos += 5;
    }
    else
    {
        currentV_Pos -= 5;
    }
    V_setV_arrowPos(currentV_Pos);
}
/**
 * @brief : 垂直位置偏移重置
 * @param {*}
 * @return {*}
 */
static void onV_Pos_Reset(void)
{
    currentV_Pos = 0;
    V_setV_arrowPos(0);
}
/**
 * @brief : 水平位置偏移重置
 * @param {*}
 * @return {*}
 */
static void onH_Pos_Reset(void)
{
    currentH_Pos = 0;
    V_setH_arrowPos(0);
}
/**
 * @brief : 触发电压重置按钮监听
 * @param {*}
 * @return {*}
 */
static void onTriggerReset(void)
{
    CursorList[CURSOR_5].pos = Y_MIDDEL;
    setOscilTrigVoltage(0);
}

//触发旋钮移动一个刻度格子需要旋转多少下
#define TRIGGER_VOLTAGE_DIFF 10
/**
 * @brief : 触发电压调节旋钮监听
 * @param {*}
 * @return {*}
 */
static void onTriggerRotated(uint8_t dir)
{
    float offset = currentV_ScareValue / ((float)TRIGGER_VOLTAGE_DIFF);
    float value;
    if (dir == ENCODER_CW)
    {
        value = getOscilTrigVoltage() + offset;
    }
    else
    {
        value = getOscilTrigVoltage() - offset;
    }

    setOscilTrigVoltage(value);
    CursorList[CURSOR_5].measureValue = value;
    CursorList[CURSOR_5].measureUnit = "V";

    CursorList[CURSOR_5].pos = (int)(Y_MIDDEL - (getOscilTrigVoltage() / currentV_ScareValue) * PIXEL_PER_SCALE);
    CursorList[CURSOR_5].isVisible = 1;
    currentTrigLinePos = CursorList[CURSOR_5].pos;
}
/**
 * @brief : F1按钮监听
 * @param {*}
 * @return {*}
 */
static void onF1ButtonClicked(void)
{
    setOscilTrigType(TRIG_TYPE_FALLING);
    //printf("TRIG_TYPE_FALLING\n");
}
/**
 * @brief : F2按钮监听
 * @param {*}
 * @return {*}
 */
static void onF2ButtonClicked(void)
{
    setOscilTrigType(TRIG_TYPE_RISING);
    //printf("TRIG_TYPE_RISING\n");
}
static void onF3ButtonClicked(void)
{

    printf("f3 clicked\n");
}
static void onF4ButtonClicked(void)
{
    printf("f4 clicked\n");
}
static void onF5ButtonClicked(void)
{
    printf("f5 clicked\n");
}